package com.ihr360.payroll.controller.attendanceplan;

import com.ihr360.authority.sharing.annonation.RestControl;
import com.ihr360.authority.sharing.privilege.AccessControlMethod;
import com.ihr360.commons.entity.AuthUserInfo;
import com.ihr360.commons.exception.Ihr360Exception;
import com.ihr360.commons.model.type.WorkHourType;
import com.ihr360.commons.request.Ihr360SearchBody;
import com.ihr360.commons.utils.RestToReturnUtils;
import com.ihr360.maven.plugin.ModuleCodeStore;
import com.ihr360.maven.plugin.annotation.FunctionDefinition;
import com.ihr360.maven.plugin.annotation.ModuleDefinition;
import com.ihr360.payroll.model.dto.attendance.plan.AttendancePlan;
import com.ihr360.payroll.model.dto.attendance.rule.enroll.EnrollAdjustRule;
import com.ihr360.payroll.model.dto.attendance.rule.overtime.OvertimeRule;
import com.ihr360.payroll.model.dto.attendance.rule.personalleave.PersonalLeaveRule;
import com.ihr360.payroll.model.dto.attendance.rule.sickleave.SickLeaveRule;
import com.ihr360.payroll.service.attendanceplan.AttendancePlanService;
import com.ihr360.payroll.service.attendanceplan.EnrollAdjustRuleService;
import com.ihr360.payroll.service.attendanceplan.OvertimeRuleService;
import com.ihr360.payroll.service.attendanceplan.PersonalLeaveRuleService;
import com.ihr360.payroll.service.attendanceplan.SickLeaveRuleService;
import com.ihr360.payroll.service.attendanceplan.WorkHourTemplateService;
import com.ihr360.rest.service.SimpleRestService;
import com.ihr360.rest.webmvc.AbstractRestSimpleWithLongIdController;
import com.ihr360.validation.ValidationUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * @author tomtao
 */
@Api(value = "考勤记薪方案相关接口 admin")
@RestController
@RequestMapping("/attendancePlans/admin")
@ModuleDefinition(mainModuleCode = ModuleCodeStore.Module.SALARY_CODE_ADMIN,
        mainModuleName = ModuleCodeStore.Module.SALARY_NAME_ADMIN,
        subModuleCode = ModuleCodeStore.Module.SalaryAdmin.SALARY_SETTING_CODE,
        subModuleName = ModuleCodeStore.Module.SalaryAdmin.SALARY_SETTING_NAME,
        hasExtendsAbstractRestController = true)
@RestControl(controls = {
        AccessControlMethod.METHODS.batchDelete,
        AccessControlMethod.METHODS.deleteOne,
        AccessControlMethod.METHODS.create,
        AccessControlMethod.METHODS.getAll,
        AccessControlMethod.METHODS.getAllInCompany,
        AccessControlMethod.METHODS.update})
public class AttendancePlanAdminController extends AbstractRestSimpleWithLongIdController<AttendancePlan> {

    private static final Logger logger = LoggerFactory.getLogger(AttendancePlanAdminController.class);

    @Autowired
    AttendancePlanService attendancePlanService;
    @Autowired
    WorkHourTemplateService workHourTemplateService;
    @Autowired
    private EnrollAdjustRuleService enrollAdjustRuleService;
    @Autowired
    private OvertimeRuleService overtimeRuleService;
    @Autowired
    private PersonalLeaveRuleService personalLeaveRuleService;
    @Autowired
    private SickLeaveRuleService sickLeaveRuleService;

    @Override
    public SimpleRestService<AttendancePlan, Long> getSimpleRestService() {
        return attendancePlanService;
    }


    @FunctionDefinition(functionName = "删除", functionCode = ModuleCodeStore.Function.ATTENDANCE_PLAN)
    @DeleteMapping(value = "/delete/{id}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public boolean deleteById(@PathVariable Long id) {
        if (attendancePlanService.isReferenced(id, false)) {
            ValidationUtils.reject("", "被引用不能删除！");
        }
        try {
            return attendancePlanService.deleteSystemTemplateById(id);
        } catch (Ihr360Exception e) {
            throw e;
        } catch (DataIntegrityViolationException e) {
            logger.warn(e.getMessage(), e);
            throw new Ihr360Exception(null, "要删除的数据已被其他数据关联，无法删除");
        } catch (Exception e) {
            logger.warn(e.getMessage(), e);
            throw new Ihr360Exception(null, "无法删除数据，请刷新后重试");
        }

    }

    @FunctionDefinition(functionName = "获取一个计薪资方案", functionCode = ModuleCodeStore.Function.ATTENDANCE_PLAN)
    @ApiOperation(value = "获取一个计薪资方案")
    @Override
    public ResponseEntity get(@PathVariable(name = "id") Long id, @RequestParam(name = "projection", required = false) String projection) {
        AttendancePlan attendancePlan = attendancePlanService.getOneSystemTemplate(id);
        return toResource(attendancePlan, projection);
    }

    @FunctionDefinition(functionName = "修改工时类型", functionCode = ModuleCodeStore.Function.ATTENDANCE_PLAN)
    @ApiOperation(value = "修改工时类型")
    @PostMapping(value = "/changeWorkHourType/{planId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public boolean changeWorkHourType(@PathVariable Long planId, @RequestBody WorkHourType type) {
        return attendancePlanService.changeSystemTemplateWorkHourType(planId, type);
    }

    @FunctionDefinition(functionName = "保存考勤计薪资规则", functionCode = ModuleCodeStore.Function.ATTENDANCE_PLAN)
    @ApiOperation(value = "保存考勤计薪资规则")
    @PutMapping(value = "/save", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public void save(@RequestBody AttendancePlan entity, AuthUserInfo userInfo) {
        ValidationUtils.rejectIfEmpty(entity.getName(), "", "方案名称不能为空！");
        if (attendancePlanService.isDuplicateNameSystemTemplate(entity.getName(), entity.getId())) {
            ValidationUtils.reject("", "方案名称\"" + entity.getName() + "\"已存在！");
        }
        entity.setCompanyId(userInfo.getCompanyId());
        entity.setUpdatedAt(new Date());
        attendancePlanService.saveSystemTemplate(entity);
        RestToReturnUtils.setMessage("保存成功！");
    }

    @FunctionDefinition(functionName = "用户查询考勤计薪规则", functionCode = ModuleCodeStore.Function.ATTENDANCE_PLAN)
    @ApiOperation(value = "用户查询考勤计薪规则")
    @Override
    public ResponseEntity executeSearch(@RequestBody Ihr360SearchBody<AttendancePlan> searchBody,
                                        @RequestParam(name = "projection", required = false) String projection) {
        Page<AttendancePlan> page = attendancePlanService.searchSystemTemplate(searchBody);
        return toResource(page, projection);
    }

    @FunctionDefinition(functionName = "保存或更新入离职调整规则", functionCode = ModuleCodeStore.Function.ATTENDANCE_PLAN)
    @PostMapping(value = "/enrollAdjustRules/save")
    public boolean saveEnrollAdjustRules(@RequestBody EnrollAdjustRule enrollAdjustRule){
        enrollAdjustRuleService.save(enrollAdjustRule);
        return true;
    }

    @FunctionDefinition(functionName = "保存或更新加班规则", functionCode = ModuleCodeStore.Function.ATTENDANCE_PLAN)
    @PostMapping(value = "/overtimeRules/save")
    public boolean saveOvertimeRules(@RequestBody OvertimeRule overtimeRule){
        overtimeRuleService.save(overtimeRule);
        return true;
    }

    @FunctionDefinition(functionName = "保存或更新事假扣款规则", functionCode = ModuleCodeStore.Function.ATTENDANCE_PLAN)
    @PostMapping(value = "/personalLeaveRules/save")
    public boolean savePersonalLeaveRules(@RequestBody PersonalLeaveRule personalLeaveRule){
        personalLeaveRuleService.save(personalLeaveRule);
        return true;
    }

    @FunctionDefinition(functionName = "保存或更新病假扣款", functionCode = ModuleCodeStore.Function.ATTENDANCE_PLAN)
    @PostMapping(value = "/sickLeaveRules/save")
    public boolean saveSickLeaveRules(@RequestBody SickLeaveRule sickLeaveRule){
        sickLeaveRuleService.save(sickLeaveRule);
        return true;
    }

}
